home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Periodicals / develop / develop 7 code / C++ Exceptions / Exceptions.h < prev   
Encoding:
C/C++ Source or Header  |  1991-06-04  |  4.2 KB  |  138 lines  |  [TEXT/MPS ]

  1. /*------------------------------------------------------------------------------------------
  2.  
  3.     File:        Exceptions.h
  4.     Desc:        Exception handling mechanism & macros for C++ (and C)
  5.     
  6.     Michael C. Greenspon, Integral Information Systems, Berkeley, CA
  7.     (415) 524-5200; Alink: INTEGRAL; Internet: mcg@violet.berkeley.edu
  8.  
  9.     Based on original by Andrew Shebanow (original version by Andy Heninger)
  10.     of Apple Macintosh Developer Technical Support
  11.  
  12.     Portions Copyright © 1989-1990 Apple Computer, Inc.
  13.     All rights reserved.
  14.  
  15.     See original as distributed with sample code #14 for theory of operation
  16.  
  17. ------------------------------------------------------------------------------------------*/
  18.  
  19. #ifndef __EXCEPTIONS__
  20. #define __EXCEPTIONS__
  21.  
  22. #ifndef __TYPES__
  23. #include <Types.h>
  24. #endif
  25.  
  26. #ifndef    __ERRORS__
  27. #include <Errors.h>
  28. #endif
  29.  
  30. #ifndef __SETJMP__
  31. #include <SetJmp.h>
  32. #endif
  33.  
  34. // In the MacApp kit...
  35. #include "UFailure.h"
  36.  
  37. #ifdef    __cplusplus
  38. extern "C" {
  39. #endif
  40. // Since we eat the error code and message that the MacApp failure unit
  41.     // passes us, we need to store them someplace where your failure
  42.     // handling code can get at it. We use global variables (keen, eh?).
  43.     extern long gFailMessage;        // Current failure message
  44.     extern short gFailError;        // Current failure error
  45.  
  46.     pascal void StandardHandler(short e, long m, void* Handler_StaticLink);
  47. #ifdef    __cplusplus
  48. };
  49. #endif
  50.  
  51. // 6 Mar 91 mcg
  52. //
  53. // Hah! Just a little macro tweaking here and now we can write:
  54. //
  55. //        try {
  56. //            stuff that might throw an exception;
  57. //        }
  58. //        catch {
  59. //            do stuff to recover;
  60. //            break;    // exit handler, recovered
  61. //        }
  62. //
  63. //
  64. //    Or:
  65. //
  66. //        try something;
  67. //        catch break;
  68. //
  69. //    which recovers from all exceptions without further checking.
  70. //    Falling through the bottom of the catch (without doing a break or goto)
  71. //    signals the next handler up the chain by calling Failure() again.
  72. //
  73. //    Also you can do a break in a try block which just falls out of the try
  74. //    The catch is only executed by something in the try throwing an exception
  75. //
  76. //    So now this follows C structuring syntax and is also closer in syntax to
  77. //  proposed C++ exception handling mechanisms
  78. //
  79. //    errata: you can only have one try...catch pair per block. If you want more than
  80. //    one, enclose the pair in its own block. But try is often within a block (if, while)
  81. //    anyway, so not really a big deal. Nesting try/catch pairs within try/catch blocks
  82. //    is no prob and often useful.
  83. //
  84. //    Never allow your destructors to throw exceptions. Period.
  85. //
  86. //    And, obviously, there must be a catch for every try...
  87. //
  88. //    Be careful not to declare auto objects that require destruction within a try block.
  89. //    If you get an exception, the autos will be out of scope in the catch but no one will
  90. //    have called the destructor. Be sure to destroy other autos (eg., those with function
  91. //    scope) explicitly within the catch block by calling their destructors before throwing
  92. //    to the next handler. Syntax is obj.Class::~Class(); in the MPW 3.1 version of CFront,
  93. //    you must specify the Class:: qualifier, so this doesn't work polymorphically.
  94. //    This is a deficiency in CFront as compared with C++ ARM which specifies obj.~Class()
  95. //    as a valid virtual call syntax.
  96. //
  97. //    Also watch out for macro expansions in constructors with CFront 1.0. It has been
  98. //    known to screw up on occasion. Look at the C code if you're having problems. 
  99. //
  100. //    MPW C does a very good job of optimizing out the loops, making the generated code
  101. //    comparable to the previous versions.
  102. //
  103.  
  104.  
  105. #define try \
  106.         jmp_buf errorBuf; \
  107.         if (! setjmp(errorBuf) ) { \
  108.             FailInfo    fi; \
  109.             CatchFailures(&fi, StandardHandler, errorBuf); \
  110.             do { \
  111.  
  112. #define catch \
  113.             } while (0); \
  114.             Success(&fi); \
  115.             } \
  116.         else \
  117.             for(; (1); Failure(gFailError, gFailMessage))
  118.  
  119.  
  120. /*
  121.     The default MacApp/Object Pascal semantics are that returning from
  122.     an error handler will go to the next failure handler on the
  123.     stack.  The way we do this in C++ is that we call failure
  124.     again with the same error information.  We can use a goto (break) out
  125.     of the catch block to stop the error processing.
  126.  */
  127.  
  128. // Should go in UFailure.h
  129.  
  130. #ifdef __cplusplus
  131. inline void FailInit(Boolean t) { if (t) Failure(memFullErr,0); }
  132. #else
  133. #define    FailInit(t)        { if (t) Failure(memFullErr,0); }
  134. #endif
  135.  
  136.  
  137. #endif
  138.